/*
 * Copyright 2020 The Kubernetes Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

@use 'sass:math';
@import '../ExpandableSection/mixins';

/* For commentary, to avoid super wide lines of text in large windows.  */
$max-column-width: 77em;

/** Terminal font size */
$terminal-font-size: 0.875rem;

/** Inset of the <input> element w.r.t. the bordered/backgrounded region */
$inset: 1em;

/** Font size of e.g. timestamp */
$right-element-font-size-factor: math.div(11, 12);
$right-element-font-size: $right-element-font-size-factor + em;

/** Sizing for Block action buttons */
$action-padding: 3px;
$action-width: 2em;

/** Color to indicate focused block */
$focus-color: var(--color-brand-01);

$input-bg: var(--color-sidecar-background-02);
$input-bg-inverted: var(--color-sidecar-background-02);
$input-border: 1px solid rgba(150, 150, 150, 0.075);
$input-border-editing: var(--color-brand-03);

/** This is the left-hand border that defines each block region */
$block-border-width-px: math.div(6, 16);
$block-border-width: $block-border-width-px + em;

$input-padding-left: 1.25em;
$input-padding-right: $input-padding-left;
$repl-context-min-width: 2em;
$repl-context-margin-right: 0.5em;

/** Hover hysteresis for showing action buttons */
$action-hover-delay: 210ms;

@mixin FlushToContainer {
  margin: 0;
  padding: 0;
  max-width: unset;
}

@mixin Scrollback {
  .kui--scrollback {
    @content;
  }
}

@mixin ScrollbackInvertedColors {
  @include Scrollback {
    &.kui--inverted-color-context {
      @content;
    }
  }
}

@mixin LeftStrip {
  &[data-position='left-strip'] {
    @content;
  }
}

@mixin RightStrip {
  &[data-position='right-strip'] {
    @content;
  }
}

@mixin ScrollbackBlockList {
  .kui--scrollback-block-list {
    @content;
  }
}

@mixin ScrollbackBlockListInner {
  .kui--scrollback-block-list-for-sizing {
    @content;
  }
}

@mixin IsNotFocusedSplit {
  &:not([data-is-focused]) {
    @content;
  }
}

@mixin NotFocusedSplit {
  @include Scrollback {
    @include IsNotFocusedSplit {
      @content;
    }
  }
}

@mixin SplitContainer {
  .kui--terminal-split-container {
    @content;
  }
}

@mixin WidthConstrained {
  @include Scrollback {
    &[data-is-width-constrained] {
      @content;
    }
  }
}

@mixin PlainTerminal {
  @include Scrollback {
    &:not([data-is-width-constrained]) {
      @content;
    }
  }
}

@mixin Block {
  li.repl-block {
    @content;
  }
}

@mixin IsActive {
  &.repl-active {
    @content;
  }
}

@mixin IsNotActive {
  &:not(.repl-active) {
    @content;
  }
}

@mixin IsNotAnnouncement {
  &:not([data-announcement]) {
    @content;
  }
}

@mixin BlockFocusAttributes {
  &:focus,
  &[data-is-focused] {
    @content;
  }
}
@mixin BlockNotFocusedAttributes {
  &:not(:focus):not([data-is-focused]) {
    @content;
  }
}
@mixin FocusedBlock {
  @include Block {
    @include BlockFocusAttributes {
      @content;
    }
  }
}

@mixin BlockAfterBlock {
  li.repl-block + li.repl-block {
    @content;
  }
}

@mixin MaximizedBlock {
  @include Block {
    &[data-is-maximized] {
      @content;
    }
  }
}

@mixin NotMaximizedBlock {
  @include Block {
    &:not([data-is-maximized]) {
      @content;
    }
  }
}

@mixin BlockHoverOrFocus {
  @include Scrollback {
    @include Block {
      &:focus {
        @include InputWrapper {
          @content;
        }
      }
    }
    @include FinishedBlock {
      @include InputWrapper {
        &:hover {
          @content;
        }
      }
    }
  }
}

/** A "T T" layout, i.e. two terminals side-by-side */
@mixin SideBySide {
  .kui-tab-content:not([data-has-right-stripe]):not([data-has-left-strip]) {
    .repl .kui--terminal-split-container {
      &[data-split-count='2'],
      &[data-split-count='4'],
      &[data-split-count='5'],
      &[data-split-count='6'],
      &[data-split-count='7'],
      &[data-split-count='8'] {
        @content;
      }
    }
  }
}

@mixin DisappearOnHover {
  opacity: 0; /* rather than display: none to avoid reflow on hover */
  transition-delay: $action-hover-delay;
}

@mixin BlockBorder {
  &:before {
    @content;
  }
}

@mixin Error {
  &.error {
    @content;
  }
}

@mixin ErrorBlock {
  @include Block {
    @include Error {
      @content;
    }
  }
}

@mixin ActiveBlock {
  @include Block {
    @include IsActive {
      @content;
    }
  }
}

@mixin ProcessingBlock {
  @include Block {
    &.processing {
      @content;
    }
  }
}

@mixin FinishedBlock {
  @include Block {
    @include IsNotActive {
      @content;
    }
  }
}

@mixin OutputOnly {
  &[data-is-output-only] {
    @content;
  }
}

@mixin NotOutputOnly {
  &:not([data-is-output-only]) {
    @content;
  }
}

@mixin FinishedBlockWithOutputOnly {
  @include FinishedBlock {
    @include OutputOnly {
      @content;
    }
  }
}

@mixin FinishedBlockWithInputAndOutput {
  @include FinishedBlock {
    @include NotOutputOnly {
      @include BlockOutput {
        &.repl-result-has-content {
          @content;
        }
      }
    }
  }
}

@mixin FinishedBlockWithNoOutput {
  @include FinishedBlock {
    @include NotOutputOnly {
      @include BlockOutput {
        &:not(.repl-result-has-content) {
          @content;
        }
      }
    }
  }
}

@mixin IsReplayedBlock {
  &[data-is-replay] {
    @content;
  }
}

@mixin ReplayedBlock {
  @include FinishedBlock {
    @include IsReplayedBlock {
      @content;
    }
  }
}

/** Use this mixin as a decorator of e.g. ReplayedBlock or FinishedBlock */
@mixin NotEditableAndExecutable {
  &[data-is-executable]:not([data-is-editable]) {
    @content;
  }
}

@mixin Editable {
  &[data-is-editable] {
    @content;
  }
}
@mixin NotEditable {
  &:not([data-is-editable]) {
    @content;
  }
}

/** Hide the In[1] bits */
@mixin HideContext {
  .repl-context {
    display: none;
  }
}
@mixin HideIn {
  @include Block {
    &[data-is-output-only],
    &:not([data-is-replay]) {
      @include HideContext;
    }
  }
}

/** The element that encloses Context and InputWrapper */
@mixin ContextAndInput {
  .kui--input-and-context {
    @content;
  }
}

@mixin Context {
  .repl-context {
    @content;
  }
}

@mixin ContextInner {
  .repl-context-inner {
    @content;
  }
}

/** The wrapper around the <input> element. This contains the <input> and the timestamp, duration, and block buttons. */
@mixin InputWrapper {
  .repl-input-element-wrapper {
    @content;
  }
}

/** Same as InputWrapper, but as an immediate descendant of Block, not
  part of some outer-enclosing Block such as might happen with a
  guidebook replay */
@mixin InputWrapperImmediate {
  > {
    @include BlockInput {
      > {
        @include ContextAndInput {
          > {
            @include InputWrapper {
              @content;
            }
          }
        }
      }
    }
  }
}

@mixin Successful {
  &.valid-response {
    @content;
  }
}

/** The InputWrapper for blocks that have no output */
@mixin InputWrapperForEmptyBlock {
  @include FinishedBlock {
    &[data-is-empty]:not([data-is-focused]) {
      @include InputWrapper {
        @content;
      }
    }
  }
}

/** The input element itself */
@mixin Input {
  .repl-input-element {
    @content;
  }
}

/** Timestamp of block */
@mixin BlockTimestamp {
  .kui--repl-block-timestamp {
    @content;
  }
}

/** Duration of block */
@mixin BlockDuration {
  @include BlockTimestamp {
    .sub-text {
      @content;
    }
  }
}

/** Block action buttons, e.g. remove block, re-run command, ... */
@mixin BlockActions {
  .kui--block-actions-buttons {
    @content;
  }
}

@mixin BlockAction {
  .kui--block-action {
    @content;
  }
}

@mixin show-block-action-buttons {
  @include BlockActions {
    opacity: 1;
  }
}

/** Input portion of a Block */
@mixin BlockInput {
  .repl-input {
    @content;
  }
}

@mixin BlockInputWithActiveISearch {
  @include BlockInput {
    &.kui--isearch-active {
      @content;
    }
  }
}

/** Output portion of a Block */
@mixin BlockOutput {
  .repl-output {
    @content;
  }
}

@mixin CommandOutput {
  .repl-result {
    @content;
  }
}

/** Special designation for the output of experimental commands */
@mixin ExperimentalTag {
  /** Notes: Tag Carbon impl is the former; PatternFly impl is the latter */
  .kui--repl-block-experimental-tag .kui--tag,
  .kui--repl-block-experimental-tag.kui--tag {
    @content;
  }
}

/** Streaming output from jobs */
@mixin StreamingOutput {
  .repl-result-like[data-stream] {
    @content;
  }
}

/** Commentary section in a block */
@mixin Commentary {
  .kui--commentary {
    @content;
  }
}

/** Commentary card wrapper for the Commentary section */
@mixin CommentaryCard {
  .kui--commentary-card {
    @content;
  }
}

/** Specify a number of columns in the SplitContainer */
@mixin Columns($N) {
  grid-template-columns: repeat(#{$N}, 1fr);
}

/** Specify a number of rows in the SplitContainer */
@mixin Rows($N) {
  grid-template-rows: repeat(#{$N}, 1fr);
}

/** Two, three, etc. Splits in the current Tab */
@mixin Split($N) {
  @include SplitContainer {
    &[data-split-count='#{$N}'] {
      @content;
    }
  }
}

/** header for split */
@mixin SplitHeader {
  .kui--split-header {
    @content;
  }
}
@mixin SplitHeaderButton {
  .kui--split-header-button {
    @content;
  }
}

/** The Editor while editing a Commentary */
@mixin CommentaryEditor {
  .kui--commentary-editor {
    @content;
  }
}

/** The spinner element that we place either in the context [x] or near the timestamp/duration element */
@mixin Spinner {
  .kui--repl-block-spinner {
    @content;
  }
}

@mixin MarkdownTabs {
  .kui--markdown-tabs {
    @content;
  }
}

@mixin MarkdownSecondaryTabs {
  @include MarkdownTabs {
    &.pf-m-secondary {
      @content;
    }
  }
}

@mixin MarkdownTabContent {
  section.kui--markdown-tab:not([hidden]) {
    @content;
  }
}

@mixin MarkdownTabButtonContainer {
  .kui--markdown-tab {
    @content;
  }
}
@mixin ActiveTab {
  &.pf-m-current {
    @content;
  }
}
@mixin MarkdownTabButton {
  @include MarkdownTabButtonContainer {
    button {
      @content;
    }
  }
}
@mixin MarkdownActiveTabButton {
  @include MarkdownTabButtonContainer {
    @include ActiveTab {
      button {
        @content;
      }
    }
  }
}

@mixin MarkdownTabContentCard {
  .kui--markdown-tab-card {
    @content;
  }
}

@mixin MarkdownMajorParagraph {
  .kui--markdown-major-paragraph {
    @content;
  }
}

@mixin MarkdownTip {
  div.kui--markdown-tip {
    @content;
  }
}
@mixin MarkdownTipVariant($variant) {
  &.kui--markdown-tip_#{$variant} {
    @content;
  }
}

@mixin PtyOutputContainer {
  .kui--xterm-output {
    @content;
  }
}
@mixin PtyOutput {
  .xterm-container.xterm-terminated {
    @content;
  }
}

@mixin MarkdownIcon {
  .kui--markdown-icon {
    @content;
  }
}

@mixin Markdown {
  .page-content {
    @content;
  }
}

@mixin NotShowingSampleOutput {
  &:not([data-is-sample-output]) {
    @content;
  }
}

@mixin SampleOutput {
  .kui--sample-output {
    @content;
  }
}

@mixin Admonition {
  .kui--admonition {
    @content;
  }
}

$sepia-filter: sepia(0.5) opacity(0.9) contrast(0.95) blur(0.25px);
@mixin SepiaColors {
  --kui--sepia-filter: #{$sepia-filter};
  filter: var(--kui--sepia-filter);
}

@mixin SepiaBlockTarget {
  @include FinishedBlock {
    &:not(:hover) {
      @include InputWrapperImmediate {
        @content;
      }
    }
  }
}

/**
 * Normally, certain elements will have a min-width: 0, which allows
 * the flex box to adjust to reduced width. In some cases, e.g. areas
 * we know will be particularly narrow, we probably would rather have
 * horizontal overflow than wrapping.
 *
 * Future Devs: update the rules here as we define other regions (in
 * addition to Commentary) that have this property.
 */
@mixin WrapNormally {
  @include Commentary {
    min-width: unset;
  }
}
